package com.winit.project.core.branch;

import com.alibaba.fastjson.JSONObject;
import com.winit.common.util.*;
import com.winit.core.ci.vcs.SVN;
import com.winit.deploy.bean.DeployEnum;
import com.winit.deploy.util.DeployUtil;
import com.winit.jumpServer.task.PushStatusEnum;
import com.winit.project.core.bean.PackageTypeEnum;
import com.winit.project.core.bean.ProjectInfo;
import com.winit.project.core.bean.ProjectSqlInfo;
import com.winit.project.core.bean.VcsTypeEnum;
import com.winit.project.core.build.ProjectBuilder;
import com.winit.project.core.code.ProjectCode;
import com.winit.project.core.edition.EditionCleaner;
import com.winit.project.core.edition.PackageEdition;
import com.winit.project.core.edition.PackageEditionConfig;
import com.winit.project.core.set.ProjectSetConfig;
import com.winit.project.handler.BuildHandler;
import com.winit.project.task.BuildStatusEnum;
import com.winit.project.util.ProjectMessageUtil;
import com.winit.project.util.ProjectUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by wangjian on 16/9/6.
 */
public class Project extends Branch {

    private static final Logger logger = LoggerFactory.getLogger(Project.class);

    private String path;
    private ProjectSetConfig projectSetConfig;
    private ProjectConfig projectConfig;
    private ProjectStatus projectStatus;
    private ProjectBuilder projectBuilder = null;

    private ProjectCode projectCode = null;

    public ProjectInfo projectInfo;

    public Project(String projectName, boolean loadInfo) throws Exception {
        super(projectName);
        this.path = ProjectUtil.getProjectFilePath(projectName);
        this.projectConfig = new ProjectConfig(projectName, loadInfo);
        this.projectStatus = new ProjectStatus(projectName, loadInfo);
        this.projectSetConfig = new ProjectSetConfig(projectName, loadInfo);
        this.projectInfo = this.setProjectInfo();
    }

    /**
     * 获取构建日志路径
     *
     * @return
     * @throws Exception
     */
    public String getBuildLogFilePath() throws Exception {
        return this.getProjectBuilder().getBuildLogFilePath();
    }

    public boolean isProjectExist() {
        File file = new File(this.path);
        return file.exists();
    }

    public boolean isEditionExist(String editionNum) {
        File file = new File(this.path + editionNum);
        return file.exists();
    }

    public List<PackageEdition> listEditions(boolean loadInfo) throws Exception {
        return this.listEditions(loadInfo, true);
    }

    /**
     * 获取工程版本列表
     *
     * @param loadInfo   是否加载版本信息
     * @param hasDefault 是否显示default版本
     * @return
     * @throws Exception
     */
    public List<PackageEdition> listEditions(boolean loadInfo, boolean hasDefault) throws Exception {
        logger.info("获取工程版本列表,projectName=" + this.projectName);
        File file = new File(this.path);
        if (!file.exists()) {
            logger.error("获取工程版本列表,工程目录不存在.projectName=" + this.projectName);
            throw new Exception("获取工程版本列表,工程目录不存在.projectName=" + this.projectName);
        }
        List<PackageEdition> list = new ArrayList<>();
        for (File f : file.listFiles()) {
            if (!f.isDirectory()) {
                continue;
            }
            if (!f.getName().contains("-")) {
                continue;
            }
            list.add(new PackageEdition(this.projectName, f.getName(), loadInfo));
        }
        Collections.sort(list, new Comparator<PackageEdition>() {
            @Override
            public int compare(PackageEdition o1, PackageEdition o2) {
                String edition1 = o1.getEditionNum();
                String edition2 = o2.getEditionNum();
                return edition2.compareTo(edition1);
            }
        });
        ProjectBuilder builder = new ProjectBuilder(this.projectName, null);
        File builderFile = new File(builder.getPath());
        if (hasDefault && builderFile.exists()) {
            list.add(0, new PackageEdition(this.projectName, builder.getBuildDir(), loadInfo));
        }
        return list;
    }

    /**
     * 新增工程时,创建工程构建目录default
     *
     * @return
     * @throws Exception
     */
    public boolean createBuildDir() throws Exception {
        String buildDir = this.getProjectBuilder().getBuildDir();
        logger.info("新建工程,创建构建目录.projectName=" + this.projectName);
        ProjectUtil.createEditionDir(this.projectName, buildDir);
        PackageEdition edition = this.getEdition(buildDir, false);
        PackageEditionConfig editionConfig = edition.getPackageEditionConfig();
        editionConfig.setProtected(false);
        editionConfig.saveToFile();
        return true;
    }

    public String createNewEdition() throws Exception {
        logger.info("创建新版本,projectName=" + this.projectName);
        String buildStatus = this.projectStatus.getBuildStatus();
        if (!buildStatus.equals(BuildStatusEnum.BUILD_SUCCESS.getDesc())) {
            logger.warn("创建新版本,该工程没有进行过构建或构建失败.projectName" + this.projectName + ",buildStatus=" + buildStatus);
            throw new Exception("创建新版本,该工程没有进行过构建或构建失败");
        }

        //删除多余版本
        this.rmEdition();

        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd-HHmmss");
        String editionNum = format.format(new Date());
        //将war包从构建目录挪至版本目录
        String fromPath = this.getProjectBuilder().getPath();
        String toPath = this.path + editionNum;
        String str = ShellRunUtil.runCmds("cp", "-Rf", fromPath, toPath);
        if (!StringUtils.isEmpty(str)) {
            logger.error("创建新版本,拷贝异常.projectName=" + this.projectName + ",desc=" + str);
            throw new Exception("创建新版本,拷贝异常.projectName=" + this.projectName + ",desc=" + str);
        }

        PackageEdition buildEdition = this.getEdition(ProjectUtil.BUILD_DIR, true);
        PackageEditionConfig buildEditionConfig = buildEdition.getPackageEditionConfig();


        //保存版本信息
        PackageEdition edition = this.getEdition(editionNum, false);
        PackageEditionConfig editionConfig = edition.getPackageEditionConfig();
        String nasNum = ProjectUtil.getEditionNasNum(edition.getPath());
        editionConfig.setProtected(false);
        editionConfig.setNasNum(nasNum);
        editionConfig.setCreateDate();
        editionConfig.setSvnVersion(buildEditionConfig.getSvnVersion());
        editionConfig.saveToFile();
        this.updateBuildStatus(BuildStatusEnum.CREATE_EDITION, this.projectName);
        return editionNum;
    }

    public boolean rmEdition() throws Exception {
        logger.info("删除旧版本,projectName=" + this.projectName);
        this.projectStatus.loadFromFile();
        EditionCleaner cleaner = new EditionCleaner(this.projectName, this.projectStatus.getQaTestEdition());
        cleaner.doClean(this.listEditions(true, false), this.getProjectBuilder().getBuildDir());
        return false;
    }

    public PackageEdition getEdition(String editionNum, boolean loadInfo) throws Exception {
        logger.info("获取工程版本信息,projectName=" + this.projectName + ",editionNum=" + editionNum);
        return new PackageEdition(this.projectName, editionNum, loadInfo);
    }

    /**
     * 构建目录构建成功后,生成新版本并提交测试
     *
     * @return
     * @throws Exception
     */
    public boolean setQaTestEdition() throws Exception {
        String editionNum = this.createNewEdition();
        return this.setQaTestEdition(editionNum);
    }

    /**
     * 指定版本提交测试
     *
     * @param editionNum
     * @return
     * @throws Exception
     */
    public boolean setQaTestEdition(String editionNum) throws Exception {
        logger.info("记录工程提交测试版本,projectName=" + this.projectName + ",editionNum=" + editionNum);
        if (!this.isEditionExist(editionNum)) {
            logger.error("记录工程提交测试版本,版本不存在.projectName=" + this.projectName + ",editionNum=" + editionNum);
            throw new Exception("记录工程提交测试版本,版本不存在.projectName=" + this.projectName + ",editionNum=" + editionNum);
        }
        this.projectStatus.loadFromFile();
        this.projectStatus.setQaTestEdition(editionNum);
        this.projectStatus.saveToFile();
        return true;
    }

    @Override
    public boolean isTrunk() {
        return this.projectName.equals(this.getName());
    }

    @Override
    public String getName() {
        return ProjectUtil.getTrunkProjectName(this.projectName);
    }

    @Override
    public String getSuffix() {
        if (isTrunk()) {
            return null;
        }
        return this.projectName.split("_")[1];
    }

    @Override
    public String getFullName() {
        return this.projectName;
    }

    public ProjectConfig getProjectConfig() {
        return projectConfig;
    }

    public ProjectStatus getProjectStatus() {
        return projectStatus;
    }

    public void setBuildHandler(BuildHandler handler) throws Exception {
        this.getProjectBuilder().setHandler(handler);
    }

    /**
     * 执行构建 对外
     *
     * @param isDeploy         构建jar工程时必填  是否发布到maven仓库
     * @param queueProjectName 当更新jar工程状态时,输出的队列应为当前调用该工程的war工程名
     * @return
     * @throws Exception
     */
    public boolean doBuild(String isDeploy, String queueProjectName) throws Exception {
        boolean flag = false;
        try {
            this.updateBuildStatus(BuildStatusEnum.ON_BUILD, queueProjectName);
            flag = this.getProjectBuilder().doBuild(this.projectSetConfig, isDeploy, this.projectConfig.isUseSonar(), this.projectConfig.getVcsPath());
            this.updateBuildStatus(BuildStatusEnum.BUILD_SUCCESS, queueProjectName);
        } catch (Exception e) {
            this.updateBuildStatus(BuildStatusEnum.BUILD_FAILED, queueProjectName);
            throw e;
        } finally {
            //保存信息
            PackageEdition edition = new PackageEdition(this.projectName, ProjectUtil.BUILD_DIR, true);
            PackageEditionConfig editionConfig = edition.getPackageEditionConfig();
            String nasNum = ProjectUtil.getEditionNasNum(edition.getPath());
            editionConfig.setProtected(false);
            editionConfig.setNasNum(nasNum);
            editionConfig.setCreateDate();
            editionConfig.saveToFile();
        }
        return flag;
    }

    public boolean isOnBuild() throws Exception {
        this.projectStatus.loadFromFile();
        String buildStatus = this.projectStatus.getBuildStatus();
        //1.工程状态为构建中或排队中
        if (BuildStatusEnum.ON_BUILD.getDesc().equals(buildStatus)
                || BuildStatusEnum.IN_QUEUE.getDesc().equals(buildStatus)) {
            logger.info("工程正在构建中,projectName=" + this.projectName + ",status=" + buildStatus);
            return true;
        }
        //2.如果不是war工程 直接返回 war工程需要判断关联jar工程的状态
        if (!PackageTypeEnum.MAVEN_WAR.getDesc().equals(this.projectSetConfig.getPackageType())) {
            return false;
        }
        //3.war工程判断关联jar工程是否在构建中
        List<JSONObject> dependency = this.projectConfig.getDependency();
        if (dependency.size() > 0) {
            for (JSONObject object : dependency) {
                String jarName = object.getString("jarName");
                Project jarProject = new Project(jarName, true);
                boolean flag = jarProject.isOnBuild();
                //关联jar正在构建中
                if (flag) {
                    logger.info("工程的关联jar正在构建中,projectName=" + this.projectName + ",jarName=" + jarName);
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 更新工程状态
     *
     * @param statusEnum
     * @param queueProjectName 当更新jar工程状态时,输出的队列应为当前调用该工程的war工程名
     * @throws Exception
     */
    public void updateBuildStatus(BuildStatusEnum statusEnum, String queueProjectName) throws Exception {
        ProjectMessageUtil.projectBuildStatusMes(queueProjectName, this.projectName, statusEnum);

        this.projectStatus.loadFromFile();
        this.projectStatus.setBuildStatus(statusEnum.getDesc());
        this.projectStatus.saveToFile();

        logger.info("执行构建,修改工程构建状态,projectName=" + this.projectName + ",status=" + statusEnum.getDesc() + ",queueProjectName=" + queueProjectName);
    }

    /**
     * 更新工程依赖的jar工程状态
     *
     * @param statusEnum
     * @throws Exception
     */
    public void updateDependencyProjectStatus(BuildStatusEnum statusEnum) throws Exception {
        if (!PackageTypeEnum.MAVEN_WAR.getDesc().equals(this.projectSetConfig.getPackageType())) {
            return;
        }
        List<JSONObject> dependency = this.projectConfig.getDependency();
        if (dependency.size() > 0) {
            for (JSONObject object : dependency) {
                String jarName = object.getString("jarName");
                Project jarProject = new Project(jarName, true);
                jarProject.updateBuildStatus(statusEnum, this.projectName);
            }
        }
    }

    private ProjectBuilder getProjectBuilder() throws Exception {
        if (this.projectBuilder != null) {
            return this.projectBuilder;
        }
        this.projectBuilder = new ProjectBuilder(this.projectName, this.getProjectCode());
        return this.projectBuilder;
    }

    public ProjectSetConfig getProjectSetConfig() {
        return projectSetConfig;
    }

    public ProjectCode getProjectCode() throws Exception {
        if (!this.isProjectExist()) {
            logger.error("获取工程ProjectCode对象,工程不存在.projectName=" + this.projectName);
            throw new Exception("获取工程ProjectCode对象,工程不存在.projectName=" + this.projectName);
        }

        if (this.projectCode != null) {
            return this.projectCode;
        }

        String vcs = this.projectSetConfig.getVcsType();
        if (StringUtils.isEmpty(vcs)) {
            logger.error("获取工程ProjectCode对象,VcsType为空!");
            throw new Exception("获取工程ProjectCode对象,VcsType为空!");
        }
        String codePath = ProjectUtil.getProjectCodePath(this.projectName);
        VcsTypeEnum vcsType = Enum.valueOf(VcsTypeEnum.class, vcs.toUpperCase());
        switch (vcsType) {
            case SVN:
                SVN svn = new SVN(this.projectConfig.getVcsPath(), codePath);
                this.projectCode = new ProjectCode(this.projectName, codePath, svn);
                break;
            default:
                break;
        }
        return this.projectCode;
    }

    public boolean doCheckOut() throws Exception {
        return this.getProjectCode().checkOutProjectCode();
    }

    public boolean doUpdate() throws Exception {
        return this.getProjectCode().checkOutProjectCode();
    }

    /**
     * 修改工程svn地址后,重新检出代码
     *
     * @return
     * @throws Exception
     */
    public boolean removeOldAndCheckNew() throws Exception {
        return this.getProjectCode().removeOldAndCheckNew();
    }

    public String getPath() {
        return path;
    }

    private ProjectInfo setProjectInfo() {
        ProjectInfo info = new ProjectInfo();
        BeanUtils.copyProperties(this.projectConfig, info);
        BeanUtils.copyProperties(this.projectSetConfig, info);
        BeanUtils.copyProperties(this.projectStatus, info);
        String version = DeployUtil.getProjectVersion(this.projectName, DeployEnum.TESTPASS, "");
        if (!StringUtils.isEmpty(version) && this.projectName.equals(version.split("#")[0])) {
            info.setTestPassEdition(version.split("#")[1]);
        }
        logger.info("获取工程信息,info=" + ObjectToString.getString(info));
        return info;
    }

    /**
     * 修改工程的跳板机推送状态
     *
     * @param statusEnum 推送状态
     * @param pushDesc   推送描述
     * @param editionNum 推送版本号
     * @throws Exception
     */
    public void updatePushStatus(PushStatusEnum statusEnum, String pushDesc, String editionNum) throws Exception {

        ProjectMessageUtil.projectPushMsg(this.projectName, statusEnum.getDesc(), pushDesc);

        this.projectStatus.loadFromFile();
        this.projectStatus.setPushStatus(statusEnum.getDesc());
        this.projectStatus.setPushDesc(pushDesc);
        this.projectStatus.setPushEdition(editionNum);
        this.projectStatus.saveToFile();

        logger.info("执行构建,修改工程跳板机推送状态,projectName=" + this.projectName + ",status=" + statusEnum.getDesc() + ",pushDesc=" + pushDesc);
    }

    /**
     * 抽取工程的sql文件
     *
     * @param dir           /usr/local/Beetle/sql/${集成计划目录}
     * @param integrationId
     * @return
     * @throws Exception
     */
    public void drawProjectSql(String dir, String integrationId, List<JSONObject> list, boolean isCopy) throws Exception {
        String path = this.getProjectCode().getCodePath();
        String trunkName = ProjectUtil.getTrunkProjectName(this.projectName);
//        this.getProjectCode().updateProjectCode();
        PackageTypeEnum packageType = Enum.valueOf(PackageTypeEnum.class, this.projectSetConfig.getPackageType().toUpperCase());

        String sqlPath = getProSqlFilePath(packageType, trunkName);
        if (sqlPath == null) {
            logger.warn("com.winit.project.core.branch.Project.drawProjectSql 工程sql目录不存在.projectName=" + this.projectName);
            throw new Exception("抽取sql文件,工程sql目录不存在.packageType=" + packageType + ",projectName=" + this.projectName);
        }

        File file = new File(path + sqlPath);
        this.getProSql(file, dir, trunkName, integrationId, list, isCopy);
    }

    public void drawProjectSql(List<JSONObject> list) throws Exception {
        this.drawProjectSql(null, null, list, false);
    }

    private void getProSql(File file, String dir, String trunkName, String integrationId, List<JSONObject> list, boolean isCopy) {
        String parent = file.getAbsolutePath();
        if (!file.exists()) {
            return;
        }
        for (File f : file.listFiles()) {
            if (f.getName().contains("lock") || f.getName().contains("local")) {
                continue;
            }
            if (!f.isDirectory() && f.getName().endsWith(".sql")) {
                this.cpAndsaveSqlInfo(dir, trunkName, integrationId, f, getSqlFileName(parent, f), list, isCopy, parent);
            } else {
                List<File> files = new ArrayList<>();
                FileUtil.getFileListF(f, files);
                if (files.size() > 0) {
                    for (File ff : files) {
                        this.cpAndsaveSqlInfo(dir, trunkName, integrationId, ff, getSqlFileName(parent, ff), list, isCopy, parent);
                    }
                }
            }
        }

    }

    private String getSqlFileName(String parent, File file) {
        return file.getAbsolutePath().replace(parent + "/", "").replace("/", "_");
    }

    private void cpAndsaveSqlInfo(String dir, String trunkName, String integrationId, File file
            , String newFileName, List<JSONObject> list, boolean isCopy, String parent) {
        if (file.isDirectory() || !file.getName().endsWith(".sql")) {
            logger.info("com.winit.project.core.branch.Project.cpAndsaveSqlInfo not sql file ." + file.getAbsolutePath());
            return;
        }

        if (!isCopy) {
            ProjectSqlInfo info = new ProjectSqlInfo();
            info.setFile_name(newFileName);
            info.setFile_path(file.getAbsolutePath());
            list.add(info.toJson());
            return;
        }

        File f = new File(dir + "/" + trunkName);
        if (!f.exists()) {
            f.mkdirs();
        }

        String path = file.getParentFile().getAbsolutePath().replace(parent, dir + "/" + trunkName);
        File parentFile = new File(path);
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }
        ShellRunUtil.runCmds("cp", LinuxUtil.dealFileName(file.getAbsolutePath()), path + "/" + LinuxUtil.dealFileName(newFileName));

        ProjectSqlInfo info = new ProjectSqlInfo();
        info.setProject_name(this.projectName);
        info.setIntegration_id(integrationId);
        info.setTrunk_name(trunkName);
        info.setFile_name(newFileName);
        info.setFile_path(path + "/" + newFileName);
        info.setFile_size(Long.toString(file.length()));
        info.setModify_date("");
        info.setFile_modify_date("");
        try {
            String time = getSvnFileLastModifyTime(file.getAbsolutePath().replace(this.getProjectCode().getCodePath(), this.getProjectConfig().getVcsPath() + "/"));
            if (time != null) {
                info.setModify_date(time);
            }
        } catch (Exception e) {
        }
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = new Date(file.lastModified());
            info.setFile_modify_date(format.format(date));
        } catch (Exception e) {
        }
        info.setMd5(Md5Util.getFileMd5(file.getAbsolutePath()));
        list.add(info.toJson());
    }

    private String getSvnFileLastModifyTime(String svnUrl) {
        String time = ShellRunUtil.runCmds("svn info " + svnUrl + " |grep -i date |awk '{print $4\" \"$5}'");
        if (!StringUtils.isEmpty(time) && !",".equals(time)) {
            return time.substring(0, time.length() - 1);
        } else {
            return null;
        }
    }

    /**
     * 获取工程的sql文件存放目录
     *
     * @param packageType
     * @param trunkName
     * @return
     */
    private String getProSqlFilePath(PackageTypeEnum packageType, String trunkName) throws Exception {
        JSONObject object = JSONFileUtil.getFileJsonForBean(Thread.currentThread().getContextClassLoader().getResource("").getPath()
                + "data/sql_file_path.json", JSONObject.class);
        if (object.containsKey(trunkName)) {
            return object.getString(trunkName);
        }
        String path = null;
        switch (packageType) {
            case MAVEN_WAR:
                path = "/src/main/resources/sql";
                break;
            case MAVEN_JAR:
                break;
            case PHP:
                path = "/script/sql";
                break;
            case ANT_ANDROID:
                break;
            case SPRING_BOOT_JAR:
                path = "/src/main/resources/sql";
                break;
            default:
                logger.error("com.winit.project.core.branch.Project.getProSqlFilePath,参数错误.packageType=" + packageType + ",projectName=" + this.projectName);
                throw new Exception("抽取sql文件,参数错误.packageType=" + packageType + ",projectName=" + this.projectName);
        }
        return path;
    }

    /**
     * 获取工程配置key  value列表
     * 只扫描工程configPath下指定的配置文件
     * java工程默认扫描 config.properties environment.properties password.properties
     * php工程默认扫描 config.php
     *
     * @return
     */
    public List<JSONObject> getConfigKeyAndValueForPro() {
        List<JSONObject> list = new ArrayList<>();
        PackageTypeEnum packageType = Enum.valueOf(PackageTypeEnum.class, this.projectSetConfig.getPackageType().toUpperCase());
        try {
            //工程代码路径
            String path = this.getProjectCode().getCodePath() + "/";
            //默认读取的配置文件放置目录  submodule+configpath
            StringBuffer configPath = new StringBuffer();
            if (!StringUtils.isEmpty(this.projectSetConfig.getSubModule())) {
                configPath.append(this.projectSetConfig.getSubModule()).append("/");
            }
            configPath.append(this.getProjectConfig().getConfigPath()).append("/");
            //1.先抽取默认配置文件
            //2.再抽取单独配置的文件
            List<String> fileList = new ArrayList<>();
            JSONObject object = JSONFileUtil.getFileJsonForBean(Thread.currentThread().getContextClassLoader().getResource("").getPath()
                    + "data/config_file_path.json", JSONObject.class);
            String trunkName = this.getName();
            if (object.containsKey(trunkName)) {
                fileList.addAll(object.getObject(trunkName, List.class));
            }
            switch (packageType) {
                case MAVEN_WAR:
                    fileList.add(configPath.toString() + "config.properties");
                    fileList.add(configPath.toString() + "application.properties");
                    fileList.add(configPath.toString() + "environment.properties");
                    fileList.add(configPath.toString() + "password.properties");
                    list = getConfigKandV(path, fileList);
                    break;
                case PHP:
                    fileList.add(configPath.toString() + "config.php");
                    list = getConfigKandV(path, fileList);
                    break;
                case SPRING_BOOT_JAR:
                    fileList.add(configPath.toString() + "config.properties");
                    fileList.add(configPath.toString() + "application.properties");
                    fileList.add(configPath.toString() + "environment.properties");
                    fileList.add(configPath.toString() + "password.properties");
                    list = getConfigKandV(path, fileList);
                    break;
                default:
                    logger.info("com.winit.project.core.branch.Project.getConfigKeyAndValueForPro 不支持配置文件抽取.packageType=" + packageType.getDesc());
                    break;
            }
        } catch (Exception e) {
            logger.error("com.winit.project.core.branch.Project.getConfigKeyAndValueForPro 异常", e);
        }
        return list;
    }

    private List<JSONObject> getConfigKandV(String path, List<String> fileList) {
        List<JSONObject> list = new ArrayList<>();
        for (String s : fileList) {
            File file = new File(path + "/" + s);
            if (!file.exists()) {
                continue;
            }
            list.addAll(FileUtil.getConfigKeyAndValue(file.getAbsolutePath()));
        }
        return list;
    }
}
